#include "uni_iot.h"
#include "uni_hal_resample.h"
#include "pwm.h"
#include "dma.h"
#include <rtthread.h>
#include "DrvUART010.h"
#include "gpio.h"
#include "uni_hal_audio_buf.h"

#define PWM_AUDIO_BUF_SIZE  (512 * 2)
#define PWM_PA_EN_GPIO      31    // power amplifier enable pin

extern ASRC_PWM_REG *asrc_pwm_reg_ptr;
static AudioBufHandler g_audio_buf_handler = NULL;

void sample_bit_convert_16_to_32(UINT16 *InBuffer, UINT32 *OutBuffer,
                                          UINT32 InBuflen) {
  UINT32 i;
  for(i = 0; i < InBuflen/sizeof(UINT16); i++) {
    OutBuffer[i] = (InBuffer[i] << 8) & 0xFFFFFFFF;
  }
}

static void _inject_audio_data(void) {
  const char *audio_buf = NULL;
  int size = 0;
  audio_buf = uni_audio_buf_read(g_audio_buf_handler, &size);
  if (audio_buf && (size > 0)) {
    fLib_DMAPlayTx_start((UINT32)(&(asrc_pwm_reg_ptr->FIFO_PORT)),
                          (UINT32)audio_buf, (UINT32)size,
                          DMA_CHANEL_RESAMPLE_TX);
  }
}

void uni_hal_PlayTx_handler(dma_event_t event, void  *user_data) {
  if( event != DMA_EVENT_TC ){
    fLib_printf("DMA error occurred!\n");
    return;
  }
  _inject_audio_data();
}

void uni_hal_resampleTx_init(void) {
  if (NULL == g_audio_buf_handler) {
    g_audio_buf_handler = uni_audio_buf_create(PWM_AUDIO_BUF_SIZE);
    if (g_audio_buf_handler) {
      fLib_DMARegisterCallback(DMA_CHANEL_RESAMPLE_TX,
                               uni_hal_PlayTx_handler, NULL);
      pwm_module_init();
      uni_set_gpio_dir(PWM_PA_EN_GPIO, 1);
      _inject_audio_data();
    }
  }
}

UINT32 uni_hal_play(UINT32 *buffer, UINT32 len) {
  return uni_audio_buf_write(g_audio_buf_handler, (char *)buffer, (int)len);
}

void uni_hal_pwm_play_mute(void) {
  uni_set_gpio_value(PWM_PA_EN_GPIO, 1);
}

void uni_hal_pwm_play_unmute(void) {
  uni_set_gpio_value(PWM_PA_EN_GPIO, 0);
  /*FIXME: should wait 90ms for pa unmute done*/
  uni_msleep(90);
}

